#pragma once

#include "CInterlockedReferenceCount.h"

#include "CMILMatrix.h"
#include "HWDependentBatch.h"
#include "HWMediaBatchInfo.h"

class HWCrossFrameResources;
class HWInstance;
class HWCompTreeNode;
class SolidColorBrushClone;
class HWTexture;
class CMILMatrix;
class CHardwareCompositor;
class HWTextRealization;
class CTileIterator;

namespace PrimitiveCompositor
{
	enum Flags
	{
		None = 0,
		EnableBatchedDrawing = 1,
		ForceShapeMaskedPrimitives = 2,
		ForceDWORD = 0xff
	};
};



class HWFrameData :
	public CInterlockedReferenceCount
{

public: 
	static HRESULT Create(HWCrossFrameResources * pCrossFrameResources, XBOOL fOverdrawHeatMapEnabled, XUINT32 backgroundColor, const CMILMatrix & orientationTransformInverse, HWFrameData * * ppHwRender);
	virtual XUINT32 AddRef();
	virtual XUINT32 Release();

	HRESULT AddRectangle(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & rect, 
		XUINT32 uColorMaskPremultiplied, 
		SolidColorBrushClone * pBrushClone, 
		enum AddressEdgeMode addressEdgeMode, 
		XUINT32 aaMask, 
		HWTexture * pShapeHwTexture, 
		const CMILMatrix * pElementToShapeTextureSpace, 
		HWTexture * pBrushHwTexture, 
		const CMILMatrix * pBrushTransform);

	HRESULT AddRectangle(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & rect, 
		XUINT32 uColorMaskPremultiplied, 
		SolidColorBrushClone * pBrushClone, 
		enum AddressEdgeMode addressEdgeMode, 
		HWTexture * pShapeHwTexture, 
		HWTexture * pBrushHwTexture, 
		const CMILMatrix * pBrushTransform);

	HRESULT AddNinegrid(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XSIZEF & elementSize, 
		const struct XSIZEF & sourceSize, 
		HWTexture * pShapeHwTexture, 
		HWTexture * pBrushHwTexture, 
		XUINT32 uColorMaskPremultiplied, 
		XUINT32 aaMaskForTile, 
		const struct XRECTF_RB * pNinegrid, 
		const XBOOL fIsHollow, 
		const struct XRECTF_WH * pTileBounds, 
		SolidColorBrushClone * pBrushClone);

	HRESULT AddVideo(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & elementBounds, 
		const CMILMatrix * pBrushTransform, 
		XUINT32 uColorMaskPremultiplied, 
		struct IXcpVideoFrameProvider * pMediaSource);

	HRESULT AddText(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & brushBounds, 
		HWTextRealization * pHwTextRealization, 
		SolidColorBrushClone * pBrushClone);

	HRESULT AddTransparentRectangle(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & elementBounds, 
		struct IXcpVideoFrameProvider * pMediaSource);

	HRESULT AddTiledRectangle(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & elementBounds, 
		enum AddressEdgeMode addressEdgeMode, 
		XUINT32 brushMask, 
		CTileIterator & tileIterator, 
		const struct XRECTF_RB * pNinegrid, 
		XBOOL fIsHollow, 
		HWTexture * pShapeHwTexture);

	HRESULT Prewalk(CHardwareCompositor * pCompositor, 
		struct IPALOptimizedGraphicsDevice * pGraphicsDevice, 
		const struct XRECTF_WH & backBufferSize, 
		XBOOL * pSwapChainNeedsAlphaMode);

	HRESULT Draw(CHardwareCompositor * pCompositor, struct IPALOptimizedGraphicsDevice * pGraphicsDevice);
	HRESULT CompleteFrame(HWInstance * pRenderList, 
		const xvector<xpair<HWCompTreeNode *,HWInstance *> > * pStartBoundaries, 
		const xvector<xpair<HWCompTreeNode *,HWInstance *> > * pEndBoundaries, 
		HWFrameData * pPreviousFrameData, 
		XBOOL * pHasContent);

	void SetIndependentPropertiesDirty(XUINT32 startSlotInclusive, XUINT32 endSlotExclusive);
	void SetDiffuse(XUINT32 slot, XUINT32 unpremultipliedDiffuse);
	XUINT32 CheckPrimitiveCompositorFlags(enum PrimitiveCompositor::Flags flagsToCheck);
	void SetKeyedMutexSequenceNumber(XUINT64 sequenceNumber);
	HRESULT RegisterMediaUpdateListener(struct IMediaUpdateListener * pListener);
	HRESULT SubmitMediaUpdateCommands(CHardwareCompositor * pHardwareCompositor);

private: 
	HWFrameData(HWCrossFrameResources * pCrossFrameResources, XBOOL fOverdrawHeatMapEnabled, XUINT32 backgroundColor, const CMILMatrix & orientationTransformInverse);
	virtual ~HWFrameData();
	HRESULT Initialize();
	static XUINT32 CalculateFinalDiffuse(XUINT32 brushDiffuse, XFLOAT opacity);
	HRESULT AddRenderData(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & rp, 
		const struct XRECTF_WH & localBounds, 
		HWTexture * pShapeHwTexture, 
		const CMILMatrix * pShapeLocalToAtlasSpaceTransform, 
		HWTexture * pBrushHwTexture, 
		const CMILMatrix * pBrushLocalToAtlasSpaceTransform, 
		XUINT32 aaMask, 
		XUINT32 uColorMaskPremultiplied,
		SolidColorBrushClone * pBrushClone, 
		struct IXcpVideoFrameProvider * pMediaSource,
		enum BlendMode blendMode, 
		enum AddressEdgeMode addressEdgeMode,
		enum IndexBufferType indexBufferType);

	HRESULT AddRenderDataForAntialiasingMethod(xvector<HWInstance *> * pRenderData, 
		const struct HWRenderParams & rp, 
		const struct XRECTF_WH & localBounds, 
		HWTexture * pShapeHwTexture, 
		const CMILMatrix * pShapeLocalToAtlasSpaceTransform,
		HWTexture * pBrushHwTexture, 
		const CMILMatrix * pBrushLocalToAtlasSpaceTransform, 
		XUINT32 aaMask, 
		XUINT32 uColorMaskPremultiplied,
		SolidColorBrushClone * pBrushClone, 
		struct IXcpVideoFrameProvider * pMediaSource, 
		enum BlendMode blendMode,
		enum AddressEdgeMode addressEdgeMode, 
		enum AntialiasingMethod antialiasingMethod);

	void GetNinegridCell(XUINT32 index, 
		const struct XRECTF_RB * pNinegrid, 
		XFLOAT logicalWidth,
		XFLOAT logicalHeight, 
		XFLOAT textureWidth, 
		XFLOAT textureHeight, 
		XBOOL fIsHollow, 
		XUINT32 * pAAMask, 
		struct XRECTF_WH * pCellLogicalBounds, 
		struct XRECTF_WH * pCellTextureBounds);

	void CalculateNinegridPositionToTextureTransform(XFLOAT textureWidth, 
		XFLOAT textureHeight, 
		const struct XRECTF_WH * pLogicalBounds, 
		const struct XRECTF_WH * pTextureBounds, 
		CMILMatrix * pPositionToTextureTransform);

	HRESULT UpdatePrimitives(struct IPALOptimizedGraphicsDevice * pGraphicsDevice, 
		const struct XRECTF_WH & backBufferSize, 
		HWCrossFrameResources * pResources);

	static HRESULT UpdatePrimitive(const struct XRECTF_WH & backBufferSize, 
		const struct HWInstanceInfo * pDependentObjectInfo, 

	struct HWInstanceInfoPersistent * pIndependentObjectInfo);

	void FindBackgroundPrimitive(CHardwareCompositor * pCompositor, 
		const struct XRECTF_WH backBufferSizeInBatch, 
		XUINT32 * pPrimitiveStartIndex, 
		XUINT32 * pBackgroundPrimitiveColor, 
		XBOOL * pHasMediaBatch, 
		XUINT32 * pGeneratedVertexCount);

	HRESULT InitializeVisibleSettingOnMediaBatches(const struct XRECTF_WH & backBufferSize);
	HRESULT PrepareForMediaBatchRendering(CHardwareCompositor * pCompositor, const struct XRECTF_WH & backBufferSize, XBOOL * pHasOverlappedMedia);
	HRESULT GenerateInstances(struct IPALOptimizedGraphicsDevice * pGraphicsDevice, XUINT32 primitiveStartIndex, XUINT32 generatedVertexCount);
	void ExpandAAMask(struct HWDependentVertexInstanceData * pInstance, XUINT32 aaMask);
	enum AntialiasingMethod DetermineAntialiasingMethod(const struct HWRenderParams & myRP, 
		const struct XRECTF_WH & bounds, 
		HWTexture * pBrushHwTexture, 
		HWTexture * pShapeHwTexture, 
		SolidColorBrushClone * pBrushClone, 
		XUINT32 uColorMaskPremultiplied);

	static XBOOL IsDependentInfoEqual(const struct HWInstanceInfo & left, const struct HWInstanceInfo & right);

	HRESULT BatchDependentInstances(HWInstance * pRenderList, 
		const xvector<xpair<HWCompTreeNode *,HWInstance *> > * pStartBoundaries, 
		const xvector<xpair<HWCompTreeNode *,HWInstance *> > * pEndBoundaries, 
		unsigned int * pInstanceCount);

	HRESULT WriteDependentInstances(HWInstance * pRenderList, XUINT32 instanceCount);
	void ComputeDirtyResources(HWFrameData * pPreviousFrameData);
	HRESULT UpdateMediaBatchVisibility(const HWFrameData * pPreviousFrameData);
	HWCrossFrameResources * m_pCrossFrameData;
	xvector<HWInstanceInfo> m_dependentInstances;
	XUINT32 m_dependentDirtyStart;
	XUINT32 m_dependentDirtyEnd;
	XUINT32 m_independentDirtyStart;
	XUINT32 m_independentDirtyEnd;
	xvector<HWDependentBatch> m_dependentBatches; 
	xvector<HWMediaBatchInfo> m_hwMediaBatchInfo; 
	XUINT64 m_keyedMutexSequenceNumber;
	XUINT32 m_frameBackgroundColor;
	XBOOL m_fOverdrawHeatMapEnabled;
	xvector<IMediaUpdateListener *> m_pMediaUpdateListeners; 
	CMILMatrix m_orientationTransformInverse;

};




